import JEditableTable from '@/components/jeecg/JEditableTable'
import { VALIDATE_NO_PASSED, getRefPromise, validateFormAndTables, validateTables } from '@/utils/JEditableTableUtil'
import { httpAction, getAction } from '@/api/manage'

export const JEditableTableMixin = {
  components: {
    JEditableTable
  },
  data() {
    return {
      title: '操作',
      visible: false,
      form: this.$form.createForm(this),
      confirmLoading: false,
      model: {},
      labelCol: {
        xs: { span: 24 },
        sm: { span: 6 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 18 }
      }
    }
  },
  methods: {

    /** 获取所有的editableTable实例 */
    getAllTable() {
      if (!(this.refKeys instanceof Array)) {
        throw this.throwNotArray('refKeys')
      }
      let values = this.refKeys.map(key => getRefPromise(this, key))
      return Promise.all(values)
    },

    /** 遍历所有的JEditableTable实例 */
    eachAllTable(callback) {
      // 开始遍历
      this.getAllTable().then(tables => {
        tables.forEach((item, index) => {
          if (typeof callback === 'function') {
            callback(item, index)
          }
        })
      })
    },

    /** 当点击新增按钮时调用此方法 */
    add() {
      if (typeof this.addBefore === 'function') this.addBefore()
      // 默认新增空数据
      let rowNum = this.addDefaultRowNum
      if (typeof rowNum !== 'number') {
        rowNum = 1
        console.warn('由于你没有在 data 中定义 addDefaultRowNum 或 addDefaultRowNum 不是数字，所以默认添加一条空数据，如果不想默认添加空数据，请将定义 addDefaultRowNum 为 0')
      }
      this.eachAllTable((item) => {
        item.add(rowNum)
      })
      if (typeof this.addAfter === 'function') this.addAfter(this.model)
      this.edit({})
    },
    /** 当点击了编辑（修改）按钮时调用此方法 */
    edit(record) {
      if (typeof this.editBefore === 'function') this.editBefore(record)
      this.visible = true
      this.activeKey = this.refKeys[0]
      this.form.resetFields()
      this.model = Object.assign({}, record)
      if (typeof this.editAfter === 'function') this.editAfter(this.model)
    },
    /** 关闭弹窗，并将所有JEditableTable实例回归到初始状态 */
    close() {
      this.visible = false
      this.eachAllTable((item) => {
        item.initialize()
      })
      this.$emit('close')
    },

    /** 查询某个tab的数据 */
    requestSubTableData(url, params, tab, success) {
      tab.loading = true
      getAction(url, params).then(res => {
        if(res && res.code === 200){
          tab.dataSource = res.data.rows
          typeof success === 'function' ? success(res) : ''
        }
      }).finally(() => {
        tab.loading = false
      })
    },
    /** 发起请求，自动判断是执行新增还是修改操作 */
    request(formData) {
      let url = this.url.add, method = 'post'
      if (this.model.id) {
        url = this.url.edit
        method = 'put'
      }
      this.confirmLoading = true
      httpAction(url, formData, method).then((res) => {
        if(res.code === 200){
          this.$emit('ok')
          this.confirmLoading = false
          this.close()
        } else {
          this.$message.warning(res.data.message);
          this.confirmLoading = false
        }
      }).finally(() => {
      })
    },

    /* --- handle 事件 --- */

    /** ATab 选项卡切换事件 */
    handleChangeTabs(key) {
      // 自动重置scrollTop状态，防止出现白屏
      getRefPromise(this, key).then(editableTable => {
        editableTable.resetScrollTop()
      })
    },
    /** 关闭按钮点击事件 */
    handleCancel() {
      this.close()
    },
    /** 确定按钮点击事件 */
    handleOk() {
      console.log('handleOk 被调用')
      /** 触发表单验证 */
      this.getAllTable().then(tables => {
        console.log('获取到的表格实例:', tables)
        if (!tables || tables.length === 0) {
          this.$message.warning('未找到表格实例，请检查 refKeys 配置')
          return Promise.reject(new Error('未找到表格实例'))
        }
        /** 先验证主表单，获取具体错误信息 */
        return new Promise((resolve, reject) => {
          this.form.validateFields((err, values) => {
            if (err) {
              console.error('主表单验证失败:', err)
              // 获取第一个错误字段的信息
              const firstErrorField = Object.keys(err)[0]
              const firstError = err[firstErrorField]
              if (firstError && firstError.errors && firstError.errors.length > 0) {
                this.$message.error(firstError.errors[0].message || '请检查表单填写是否正确')
              } else {
                this.$message.warning('请检查表单填写是否正确')
              }
              reject({ error: VALIDATE_NO_PASSED, isMainForm: true, errors: err })
            } else {
              // 主表单验证通过，继续验证子表
              resolve({ formValue: values, tables })
            }
          })
        })
      }).then(({ formValue, tables }) => {
        // 验证所有子表的表单
        return validateTables(tables).then(all => {
          return { formValue, tablesValue: all }
        }).catch(e => {
          // 子表验证失败，尝试获取更详细的错误信息
          if (e.error === VALIDATE_NO_PASSED && e.index !== undefined) {
            const failedTable = tables[e.index]
            if (failedTable) {
              // 获取验证失败的字段信息
              const notPassedIds = failedTable.notPassedIds || []
              const tooltips = failedTable.tooltips || {}
              
              if (notPassedIds.length > 0) {
                // 获取第一个失败字段的错误信息
                const firstFailedId = notPassedIds[0]
                const firstError = tooltips[firstFailedId]
                
                if (firstError && firstError.title) {
                  // 解析 inputId 获取行号和字段名
                  // inputId 格式: columnKey + rowId
                  // 尝试从 columns 中找到对应的字段名
                  const columns = failedTable.columns || []
                  let fieldName = '字段'
                  let rowNum = ''
                  
                  // 遍历 columns 找到匹配的字段
                  for (let col of columns) {
                    if (firstFailedId.startsWith(col.key)) {
                      fieldName = col.title || col.key
                      // 尝试从 rowId 中提取行号（如果 rowId 包含行号信息）
                      const rowId = firstFailedId.substring(col.key.length)
                      // 尝试从 inputValues 中找到对应的行索引
                      const inputValues = failedTable.inputValues || []
                      const rowIndex = inputValues.findIndex(row => {
                        const cleanId = failedTable.getCleanId ? failedTable.getCleanId(row.id) : row.id
                        return cleanId === rowId || row.id === rowId
                      })
                      if (rowIndex !== -1) {
                        rowNum = `第 ${rowIndex + 1} 行`
                      }
                      break
                    }
                  }
                  
                  this.$message.error(`${rowNum ? rowNum + ' ' : ''}${fieldName}：${firstError.title}`)
                } else {
                  this.$message.warning(`表格第 ${e.index + 1} 个数据验证失败，请检查必填项`)
                }
              } else {
                this.$message.warning('表格数据验证失败，请检查必填项')
              }
            } else {
              this.$message.warning('表格数据验证失败，请检查必填项')
            }
          }
          throw e
        })
      }).then(allValues => {
        console.log('表单验证通过，数据:', allValues)
        if (typeof this.classifyIntoFormData !== 'function') {
          throw this.throwNotFunction('classifyIntoFormData')
        }
        let formData = this.classifyIntoFormData(allValues)
        console.log('整理后的表单数据:', formData)
        // 发起请求
        return this.request(formData)
      }).catch(e => {
        console.error('保存过程出错:', e)
        if (e.error === VALIDATE_NO_PASSED) {
          if (e.isMainForm) {
            // 主表单验证失败已经在上面处理了
            return
          }
          // 如果有未通过表单验证的子表，就自动跳转到它所在的tab
          this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index]
          this.$message.warning('请检查表格数据填写是否正确')
        } else {
          if (e && e.message) {
            this.$message.error('保存失败: ' + e.message)
          } else {
            this.$message.error('保存失败，请检查控制台错误信息')
          }
        }
      })
    },

    /* --- throw --- */

    /** not a function */
    throwNotFunction(name) {
      return `${name} 未定义或不是一个函数`
    },

    /** not a array */
    throwNotArray(name) {
      return `${name} 未定义或不是一个数组`
    }

  }
}